﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ResourceBlender.Core;
using System.IO;
using System.Windows;
using System.Windows.Resources;

namespace ResourceBlender.Core {
    //todo: fix something with this, either move it to the RB.Core.ResourceGenerator and add a parameter to write to a zipstream or write the image files elsewhere
    public static class HtmlResourceGenerator  {
        /// <summary>
        /// Exports completion summaries to an HTML document.
        /// </summary>
        /// <param name="fileName">The file to export.</param>
        /// <param name="summaries">The list of summaries.</param>
        public static void ExportToSummaryHTML(string fileName, List<ApplicationSummary> summaries) {
            ExportToSummaryHTML(fileName, summaries, null);
        }

        /// <summary>
        /// Exports completion summaries to an HTML document.
        /// </summary>
        /// <param name="fileName">The file to export.</param>
        /// <param name="summaries">The list of summaries.</param>
        /// <param name="extraColumns">
        /// The extra columns to include, or <c>null</c>. The key specifies the column header, the value is the template for each column.
        /// The variables available are:
        ///    %EnglishName% - The language's english name.
        ///    %Code% - The culture name in the format "<languagecode2>-<country/regioncode2>".
        ///    %NumTranslations% - The number of complete translations in the language.
        /// </param>
        public static void ExportToSummaryHTML(string fileName, List<ApplicationSummary> summaries, IEnumerable<ApplicationSummary.SummaryColumn> extraColumns) {
            List<string> errors = new List<string>();
            StringBuilder sb = new StringBuilder();
            sb.Append(@"<html>
          <head>
            <title>Resource Completion ").Append(summaries.Count == 1 ? "Summary" : "Summaries").Append(@"</title>
            <meta name=""generator"" content=""ResourceBlender Express ").Append(Constants.GetVersion().ToString(3)).Append(@"""/>
            <style type=""text/css"">
            .translations {
                width: 90%;
                margin: 0 auto;
                border-collapse: collapse;
	            border: 1px solid #ccc;
            }
            .translations th {
	            padding: 7px 0;
	            font-weight: bold;
	            text-align: center;
	            border-bottom: 1px solid #ccc;
            }
            .translations td, .translations td a {
	            font-weight: normal;
            }
            .translations td {
                text-align: center;
                padding: 5px;
            }
            .translations .langname {
                text-align: right;
                padding-right: 1em;
                width: 40%;
            }
            .translations tbody tr:hover td {
	            background: #efefef;
            }
            .translations .langname img {
                padding: 0 0.4em;
            }
            .graph { 
                position: relative; /* IE is dumb */
                width: 200px; 
                border: 1px solid #BFD2FF; 
                padding: 2px;
            }
            .graph .bar { 
                display: block;
                position: relative;
                background: #BFD2FF; 
                text-align: center; 
                color: #000; 
                height: 1.2em; 
                line-height: 1.2em;
            }
            .graph .bar span { 
                position: absolute; 
                left: 1em; 
            }
          </style>
        </head>
        <body>
            <h1>Resource Completion Summary - ").Append(DateTime.Now.ToString("yyyy-MM-dd")).Append("</h1>\n");
            FileInfo info = new FileInfo(fileName);
            string imagesDir = Path.Combine(info.DirectoryName, "images");
            if(!Directory.Exists(imagesDir)) {
                Directory.CreateDirectory(imagesDir);
            }
            if(extraColumns == null)
                extraColumns = new List<ApplicationSummary.SummaryColumn>();
            byte[] buffer = new byte[1024];
            int read;
            foreach(ApplicationSummary summary in summaries) {
                sb.Append("<h2>").Append(summary.DisplayName).AppendLine(@"</h2>
            <table class=""translations"">
              <colgroup><col class=""langname""><col></colgroup>
                <thead>
                  <tr>
                    <th scope=""col"" class=""langname"">Language</th><th scope=""col"">Completion</th>");
                foreach(ApplicationSummary.SummaryColumn extraColumn in extraColumns) {
                    sb.AppendFormat("<th>{0}</th>\n", extraColumn.Header);
                }
                sb.Append(@"
                  </tr>
                </thead>
                <tbody>");
                foreach(LanguageCompletion language in summary.CompletionMap) {
                    int completionPercentage = (int)Math.Round((language.NumTranslations / (double)summary.TotalElements) * 100.0, 0);
                    if(completionPercentage > 100) {
                        completionPercentage = 100;
                    } else if(completionPercentage < 0)  {
                        completionPercentage = 0;
                    }
                    string iso3166 = Utils.GetISO3166(language.Culture);
                    string flagName = (iso3166.Length >= 2 ? iso3166.Substring(iso3166.Length - 2) : iso3166).ToLower() + ".png";
                    sb.Append(@"<tr>
                    <td class=""langname"">").AppendFormat(@"{0}<img alt=""{0}"" src=""images/{1}"" width=""16"" height=""11"" />", language.Culture.EnglishName, flagName).Append(@"</td>
                    <td><div class=""graph"" title=""").AppendFormat("{0}/{1} translations", language.NumTranslations, summary.TotalElements).Append(@"""><strong class=""bar"" style=""width: ").Append(completionPercentage).Append("%;\">").Append(completionPercentage).Append(@"%</strong></div></td>
                    ");
                    foreach(ApplicationSummary.SummaryColumn extraColumn in extraColumns) {
                        string columnContent = extraColumn.Content.Replace("%EnglishName%", language.Culture.EnglishName)
                                                                  .Replace("%Code%", language.Culture.Name)
                                                                  .Replace("%NumTranslations%",  language.NumTranslations.ToString());
                        sb.AppendFormat("<td>{0}</td>\n", columnContent);
                    }
                    sb.Append("</tr>\n");
                    string imageFile = Path.Combine(imagesDir, flagName);
                    if(!File.Exists(imageFile)) {
                        try {
                            StreamResourceInfo flagInfo = null;
                            try {
                                flagInfo = Application.GetResourceStream(new Uri("pack://application:,,,/Resources/images/flags/" + flagName, UriKind.Absolute));
                            } catch(IOException) { // no flag exists in assembly for language
                                flagInfo = Application.GetResourceStream(new Uri("pack://application:,,,/Resources/images/flags/unknown.png", UriKind.Absolute));
                            }
                            if(flagInfo != null) {
                                using(BinaryReader reader = new BinaryReader(flagInfo.Stream)) {
                                    using(BinaryWriter writer = new BinaryWriter(File.OpenWrite(imageFile))) {
                                        while((read = reader.Read(buffer, 0, buffer.Length)) > 0) {
                                            writer.Write(buffer, 0, read);
                                        }
                                        writer.Close();
                                    }
                                    reader.Close();
                                }
                            }
                        } catch(Exception ex) {
                            errors.Add(string.Format("Flag not copied for {0}: {1}", language.Culture.EnglishName, ex.Message));
                        }
                    }
                }
                sb.AppendLine("</tbody></table>");
            }
            sb.AppendLine(@"Generated by <a href=""http://www.resourceblender.com"">ResourceBlender by Harry Jennerway</a></body></html>");
            File.WriteAllText(fileName, sb.ToString());
        }
    }
}
